using System;
using Firestarter.Test.Base;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.BO;
using NUnit.Framework;

namespace FireStarterModeller.Test.BO
{
    [TestFixture]
    public class TestDMPropertyPropertyTypeSameAsBOLookupListClassIDType
    {
        [SetUp]
        public void SetupTest()
        {
            //Runs every time that any testmethod is executed
            TestUtilsDomain.SetupTest();
            BORegistry.DataAccessor = new DataAccessorInMemory();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //Code that is executed before any test is run in this class. If multiple tests
            // are executed then it will still only be called once.
            TestUtilsDomain.SetupFixture();
        }

        [TearDown]
        public void TearDownTest()
        {
            //runs every time any testmethod is complete
        }

        #region TestDMPropertyPropertyTypeSameAsBOLookupListClassIDType

        [Test]
        public void Test_CreateDMPropertyPropertyTypeSameAsBOLookupListClassIDTypeRule()
        {
            //---------------Set up test pack-------------------
            DMLookupListBusinessObject dmObjectLookupListBusinessObject = TestUtilsDMBusinessObjectLookupList.CreateUnsavedValidDMBusinessObjectLookupList();
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass(dmObjectLookupListBusinessObject.DMClass.Solution);
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(dmClass);
            dmProperty.LookupList = dmObjectLookupListBusinessObject;
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmProperty);
            Assert.IsNotNull(dmProperty.LookupList);
            Assert.IsInstanceOf(typeof(DMLookupListBusinessObject), dmProperty.LookupList);
            //---------------Execute Test ----------------------
            IBusinessObjectRule rule = new DMPropertyPropertyTypeSameAsBOLookupListClassIDType();
            ////---------------Test Result -----------------------
            Assert.IsNotNull(rule);
            Assert.AreEqual("DMPropertyPropertyTypeSameAsBOLookupListClassIDType", rule.Name);
            Assert.AreEqual(ErrorLevel.Warning, rule.ErrorLevel);
        }

//        [Test]
//        public void Test_CreateDMPropertyPropertyTypeSameAsBOLookupListClassIDTypeRule_WhenPropertyNull_ShouldRaiseError()
//        {
//            //---------------Set up test pack-------------------
//            //---------------Assert Precondition----------------
//            //---------------Execute Test ----------------------
//            try
//            {
//                new DMPropertyPropertyTypeSameAsBOLookupListClassIDType(null);
//                Assert.Fail("expected ArgumentNullException");
//            }
//            //---------------Test Result -----------------------
//            catch (ArgumentNullException ex)
//            {
//                StringAssert.Contains("Value cannot be null", ex.Message);
//                StringAssert.Contains("dmProperty", ex.ParamName);
//            }
//        }

        [Test]
        public void Test_IsValid_WhenPropertyHasNoLookupList_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(dmClass);
            IBusinessObjectRule rule = new DMPropertyPropertyTypeSameAsBOLookupListClassIDType();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmProperty.LookupList);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_IsValid_WhenNoPropertyType_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMLookupListBusinessObject dmObjectLookupListBusinessObject = TestUtilsDMBusinessObjectLookupList.CreateUnsavedValidDMBusinessObjectLookupList();
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass(dmObjectLookupListBusinessObject.DMClass.Solution);
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(dmClass);
            dmProperty.LookupList = dmObjectLookupListBusinessObject;
            dmProperty.PropertyType = null;
            IBusinessObjectRule rule = new DMPropertyPropertyTypeSameAsBOLookupListClassIDType();

            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmProperty.LookupList);
            Assert.IsNull(dmProperty.PropertyType);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_IsValid_WhenProperty_LookupList_IsNotBusinessObjectLookupList_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMLookupListSimple lookupList = TestUtilsDMLookupListSimple.CreateUnsavedValidDMLookupListSimple();
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(dmClass);
            dmProperty.LookupList = lookupList;
            IBusinessObjectRule rule = new DMPropertyPropertyTypeSameAsBOLookupListClassIDType();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmProperty.LookupList);
            Assert.IsNotNull(dmProperty.PropertyType);
            Assert.IsNotInstanceOf<DMLookupListBusinessObject>(dmProperty.LookupList);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_IsValid_Property_LookupList_HasNoClass_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMLookupListBusinessObject dmObjectLookupListBusinessObject = TestUtilsDMBusinessObjectLookupList.CreateUnsavedValidDMBusinessObjectLookupList();
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass(dmObjectLookupListBusinessObject.DMClass.Solution);
            dmObjectLookupListBusinessObject.DMClass = null;
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(dmClass);
            dmProperty.LookupList = dmObjectLookupListBusinessObject;
            IBusinessObjectRule rule = new DMPropertyPropertyTypeSameAsBOLookupListClassIDType();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmProperty.LookupList);
            Assert.IsNotNull(dmProperty.PropertyType);
            Assert.IsInstanceOf(typeof(DMLookupListBusinessObject), dmProperty.LookupList);
            Assert.IsNull(dmObjectLookupListBusinessObject.DMClass);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_IsValid_Property_LookupListClass_HasNoID_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMLookupListBusinessObject dmObjectLookupListBusinessObject = TestUtilsDMBusinessObjectLookupList.CreateUnsavedValidDMBusinessObjectLookupList();
            DMObjectIdentity dmObjectIdentity = dmObjectLookupListBusinessObject.DMClass.GetObjectID();
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass(dmObjectLookupListBusinessObject.DMClass.Solution);
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(dmClass);
            dmProperty.LookupList = dmObjectLookupListBusinessObject;
            IBusinessObjectRule rule = new DMPropertyPropertyTypeSameAsBOLookupListClassIDType();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmProperty.LookupList);
            Assert.IsNotNull(dmProperty.PropertyType);
            Assert.IsInstanceOf(typeof(DMLookupListBusinessObject), dmProperty.LookupList);
            Assert.IsNotNull(dmObjectLookupListBusinessObject.DMClass);
            Assert.IsNull(dmObjectIdentity);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_IsValid_WhenPropertyTypesAreSame_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMLookupListBusinessObject dmObjectLookupListBusinessObject = TestUtilsDMBusinessObjectLookupList.CreateUnsavedValidDMBusinessObjectLookupList();
            DMClass lookupListClass = dmObjectLookupListBusinessObject.DMClass;
            DMProperty property = TestUtilsShared.CreateUnsavedDMProperty(lookupListClass);
            DMObjectIdentity dmObjectIdentity = lookupListClass.CreateObjectIdentity(property);
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass(lookupListClass.Solution);
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(dmClass);
            dmProperty.LookupList = dmObjectLookupListBusinessObject;
            IBusinessObjectRule rule = new DMPropertyPropertyTypeSameAsBOLookupListClassIDType();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmProperty.LookupList);
            Assert.IsNotNull(dmProperty.PropertyType);
            Assert.IsInstanceOf(typeof(DMLookupListBusinessObject), dmProperty.LookupList);
            Assert.IsNotNull(dmObjectLookupListBusinessObject.DMClass);
            Assert.IsNotNull(dmObjectIdentity);
            Assert.IsFalse(dmObjectIdentity.IsCompositeKey);
            Assert.AreEqual(property.PropertyTypeString, dmProperty.PropertyTypeString);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }


        [Test]
        public void Test_IsValid_WhenLookupListClass_HasCompositeID_ShouldFail()
        {
            //---------------Set up test pack-------------------
            DMLookupListBusinessObject dmObjectLookupListBusinessObject = TestUtilsDMBusinessObjectLookupList.CreateUnsavedValidDMBusinessObjectLookupList();
            DMClass lookupListClass = dmObjectLookupListBusinessObject.DMClass;
            DMProperty property = TestUtilsShared.CreateUnsavedDMProperty(lookupListClass);
            DMObjectIdentity dmObjectIdentity = lookupListClass.CreateObjectIdentity(property);
            dmObjectIdentity.Properties.Add(TestUtilsShared.CreateUnsavedDMProperty(lookupListClass));
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass(lookupListClass.Solution);
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(dmClass);
            dmProperty.LookupList = dmObjectLookupListBusinessObject;
            IBusinessObjectRule rule = new DMPropertyPropertyTypeSameAsBOLookupListClassIDType();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmProperty.LookupList);
            Assert.IsNotNull(dmProperty.PropertyType);
            Assert.IsInstanceOf(typeof(DMLookupListBusinessObject), dmProperty.LookupList);
            Assert.IsNotNull(dmObjectLookupListBusinessObject.DMClass);
            Assert.IsNotNull(dmObjectIdentity);
            Assert.IsTrue(dmObjectIdentity.IsCompositeKey);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmProperty);
            //---------------Test Result -----------------------
            Assert.IsFalse(isValid);
            StringAssert.Contains("The property '" + dmProperty + "' on Class '" + dmProperty.Class, rule.Message);
            StringAssert.Contains("' and the ID of its Business Object Lookup Class '" + dmObjectLookupListBusinessObject.DMClass, rule.Message);
            StringAssert.Contains("' do not have the same property type.", rule.Message);
        }

        [Test]
        public void Test_IsValid_WhenPropertyTypesAreNotSame_ShouldFail()
        {
            //---------------Set up test pack-------------------
            DMLookupListBusinessObject dmObjectLookupListBusinessObject = TestUtilsDMBusinessObjectLookupList.CreateUnsavedValidDMBusinessObjectLookupList();
            DMClass lookupListClass = dmObjectLookupListBusinessObject.DMClass;
            DMProperty property = TestUtilsShared.CreateUnsavedDMProperty(lookupListClass);
            DMObjectIdentity dmObjectIdentity = lookupListClass.CreateObjectIdentity(property);
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass(lookupListClass.Solution);
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedDMProperty(dmClass);
            dmProperty.PropertyType = dmClass.Solution.GetDMPropertyType("System", "Double");
            dmProperty.LookupList = dmObjectLookupListBusinessObject;
            IBusinessObjectRule rule = new DMPropertyPropertyTypeSameAsBOLookupListClassIDType();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmProperty.LookupList);
            Assert.IsNotNull(dmProperty.PropertyType);
            Assert.IsInstanceOf(typeof(DMLookupListBusinessObject), dmProperty.LookupList);
            Assert.IsNotNull(dmObjectLookupListBusinessObject.DMClass);
            Assert.IsNotNull(dmObjectIdentity);
            Assert.IsNotNull(lookupListClass.GetObjectID());
            Assert.IsFalse(dmObjectIdentity.IsCompositeKey);
            Assert.AreNotEqual(property.PropertyTypeString, dmProperty.PropertyTypeString);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmProperty);
            //---------------Test Result -----------------------
            Assert.IsFalse(isValid);
        }

        [Test]
        public void Test_IsValid_WhenLookUpListClass_IDHasNoProperties_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMLookupListBusinessObject dmObjectLookupListBusinessObject = TestUtilsDMBusinessObjectLookupList.CreateUnsavedValidDMBusinessObjectLookupList();
            DMClass lookupListClass = dmObjectLookupListBusinessObject.DMClass;
            DMObjectIdentity dmObjectIdentity = lookupListClass.CreateObjectIdentity();
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass(lookupListClass.Solution);
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedDMProperty(dmClass);
            dmProperty.LookupList = dmObjectLookupListBusinessObject;
            IBusinessObjectRule rule = new DMPropertyPropertyTypeSameAsBOLookupListClassIDType();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmProperty.LookupList);
            Assert.IsNotNull(dmProperty.PropertyType);
            Assert.IsNotNull(dmObjectIdentity);
            Assert.IsFalse(dmObjectIdentity.HasProperties);
            Assert.AreEqual(0, dmObjectIdentity.Properties.Count);
            Assert.IsInstanceOf(typeof(DMLookupListBusinessObject), dmProperty.LookupList);
            Assert.IsNotNull(dmObjectLookupListBusinessObject.DMClass);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }
        #endregion
    }

}